using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
using Xfinity.Engine;
using System.Diagnostics;
using Xfinity.Materials;

namespace Xfinity.Rendering.Renderers.Deferred
{
    public class DeferredRenderer : DrawableGameComponent
    {
        private  List<Model> modelsToRender = new List<Model>();
        private Effect extractionEffect, materialEffect;
        private RenderTarget2D colourTarget; //positionTarget;
        private RenderTarget2D normalTangentTarget;
        private ContentManager content;
        public void AddModelToRenderList(Model m)
        {
            foreach (ModelMesh mesh in m.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    part.Effect = extractionEffect.Clone(GraphicsDevice);
                }
            }
            modelsToRender.Add(m);
        }

        public Effect CreateEffectFromMaterial(Material mat)
        {
            Effect e = materialEffect.Clone(GraphicsDevice);
            e.Parameters.GetParameterBySemantic("DIFFUSE").SetValue(mat.Colour);
            e.Parameters.GetParameterBySemantic("CONTRAST").SetValue(mat.Contrast);
            e.Parameters.GetParameterBySemantic("DIFFUSEMAP").SetValue(content.Load<Texture2D>(mat.DiffuseMap.Name));
            e.Parameters.GetParameterBySemantic("NORMALMAP").SetValue(content.Load<Texture2D>(mat.NormalMap.Name));

            return e;
        }

        public DeferredRenderer(Game game):base(game)
        {
            content = new ContentManager(game.Services);
        }
        
        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {
                extractionEffect = content.Load<Effect>(@"Content\Effects\scene_deferred_no_mrt");
            }
            foreach (EffectParameter param in extractionEffect.Parameters)
            {
                Debug.WriteLine(param.Semantic, param.Name);
            }
            Visible = false;

            colourTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 1, SurfaceFormat.Vector4);
            normalTangentTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 1, SurfaceFormat.Vector4);
            //positionTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 1, SurfaceFormat.Vector4);

            base.LoadGraphicsContent(loadAllContent);
        }
        public override void Draw(GameTime gameTime)
        {
            Matrix identity = Matrix.Identity;
            RenderTarget backbuffer = GraphicsDevice.GetRenderTarget(0);
            //hang on, can't the vertex positions be passed into a texture coordinate to be automatically determined?
            GraphicsDevice.SetRenderTarget(0, colourTarget);
            GraphicsDevice.SetRenderTarget(1, normalTangentTarget);
            //draw first pass
            foreach (Model model in this.modelsToRender)
            {
                foreach (ModelMesh mesh in model.Meshes)
                {
                    foreach (ModelMeshPart part in mesh.MeshParts)
                    {
                        //do stuff here.
                    }
                }
            }


            base.Draw(gameTime);
        }
    }
}
